#ifndef     __IMAGE_H
#define     __IMAGE_H


extern "C" {
#include <libavutil/mem.h>
#include <libavutil/imgutils.h>
}
#include "../../utils/nocopyable.h"
#include "./error.h"
#include <memory>

class Image : private utils::NoCopyable {

public:
    Image() {
        pointers[0] = nullptr;
    }

    bool is_empty() const {
        return pointers[0] == nullptr;
    }

    Image(int w, int h) {
        int ec = av_image_alloc(pointers, linesizes, w, h, AV_PIX_FMT_YUV420P, 1);
        if (ec < 0) {
            throw FFmpegException("av_image_alloc", ec);
        }
    }

    Image(Image&& other) {
        pointers[0] = other.pointers[0];
        pointers[1] = other.pointers[1];
        pointers[2] = other.pointers[2];
        pointers[3] = other.pointers[3];

        linesizes[0] = other.linesizes[0];
        linesizes[1] = other.linesizes[1];
        linesizes[2] = other.linesizes[2];
        linesizes[3] = other.linesizes[3];

        pts = other.pts;

        other.pointers[0] = nullptr;
    }

    ~Image() {
        if (pointers[0] != nullptr) {
            av_freep(&pointers[0]);
        }
    }

    Image& operator=(Image&& other) {
        std::swap(pointers, other.pointers);
        std::swap(linesizes, other.linesizes);
        std::swap(pts, other.pts);
        return *this;
    }

    uint8_t *pointers[4];
    int linesizes[4];
    int64_t pts;
};

using SharedImage = std::shared_ptr<Image>;

inline SharedImage make_shared_image(Image&& image) {
    return std::make_shared<Image>( std::move(image) );
}

#endif
